/**
 * @(#) NXTMotorActuator.java
 */

package pcsr.drivers.nxtDriver;

import pcsr.drivers.nxtDriver.command.INXTCommand;

class NXTMotorActuator extends NXTActuator
{
	int direction = 1;
	
	protected NXTMotorActuator( NXTPort motor, INXTCommand command ) {
		super(motor, command);
		
		SetPower((byte)50); // 50% power by default. 
		SetMode(NXTActuatorMode.BRAKE); // Brake mode
		SetRegulationMode(NXTActuatorRegulationMode.MOTORSPEED);
		SetTurnRatio((byte)0); // 0 = even power/speed distro between motors
		SetRunState(NXTActuatorRunState.RUNNING);
	}
	
	/**
	 * Causes motor to rotate forward indefinitely.
	 * @return Error value. 0 means success.
	 */
	public synchronized int forward( ) {
		direction = 1;
		SetMode(NXTActuatorMode.MOTORON);
		SetRunState(NXTActuatorRunState.RUNNING);
		SetPower((byte)(Math.abs(GetPower()* direction)));
		return SetActuatorState();
	}
	
	/**
	 * Causes motor to rotate backward.
	 * @return Error value. 0 means success.
	 */
	public synchronized int backward( ) {
		direction = -1;
		SetMode(NXTActuatorMode.MOTORON);
		SetRunState(NXTActuatorRunState.RUNNING);
		SetPower((byte)(Math.abs(GetPower()) * direction));
		return SetActuatorState();
	}
	
	/**
	 * Stops the motor using brakes.
	 * @return Error value. 0 means success.
	 */
	public synchronized int Stop( ) {
		SetRunState(NXTActuatorRunState.RUNNING);
		SetMode(NXTActuatorMode.BRAKE);
		return SetActuatorState();
	}
	
	/**
	 * Checks if motor is running.
	 * @return True if moving, false otherwise
	 */
	public synchronized boolean IsMoving( ) {
		UpdateActuatorState();
		return GetRunState() != NXTActuatorRunState.IDLE && GetMode() == NXTActuatorMode.MOTORON;
	}
	
	/**
	 * Sets motor speed.
	 * @param speed Speed value [-100;100]
	 */
	public synchronized void SetSpeed( int speed )
	{
		SetPower((byte)(Math.abs(speed) * direction));
		SetActuatorState();
	}
	
	/**
	 * Gets motor speed.
	 * @return Speed value [-100;100]
	 */
	public int GetSpeed( )
	{
		//UpdateActuatorState();
		return Math.abs(GetPower());
	}

	@Override
	public double GetActuatorValue( ) {
		return GetSpeed();
	}

	@Override
	public NXTActuatorMode[] GetAvailableModes( ) {		
		return new NXTActuatorMode[]{NXTActuatorMode.BRAKE, NXTActuatorMode.MOTORON};
	}

	@Override
	public void SetActuatorValue( double value ) {
		SetSpeed((int) value);
	}
	
	@Override
	public void SetRunState( NXTActuatorRunState runstate )
	{
		// this actuator doesn't work in other run states
		super.SetRunState(NXTActuatorRunState.RUNNING);
	}
}
